package com.llap.exp190929.security;

import com.llap.exp190929.dto.CredentialDto;
import com.llap.exp190929.error.ForbiddenException;
import com.llap.exp190929.error.RestException;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.*;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
@AllArgsConstructor
@CrossOrigin
@Slf4j
public class AuthenticationController {
    private UserAuthenticationProvider userAuthenticationProvider;
    private JwtUserDetailsService userDetailsService;
    private JwtUtil jwtUtil;

    @PostMapping("/authenticate")
    public ResponseEntity<?> createAuthenticationToken(@RequestBody CredentialDto credential) throws RestException {
        authenticate(credential.getUsername(), credential.getPassword());
        final UserDetails userDetails = userDetailsService
                .loadUserByUsername(credential.getUsername());

        final String token = jwtUtil.generateToken((JwtUser)userDetails);
        return ResponseEntity.ok(new JwtResponse(token));
    }

    private void authenticate(String username, String password) throws RestException {
        try {
            userAuthenticationProvider.authenticate(new UsernamePasswordAuthenticationToken(username, password));
        } catch (DisabledException e) {
            throw new ForbiddenException("USER_DISABLED");
        } catch (BadCredentialsException e) {
            throw new ForbiddenException("INVALID_CREDENTIALS");
        } catch (UsernameNotFoundException e) {
            throw new ForbiddenException("USERNAME_NOT_FOUND");
        }
    }
}
